/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2015年3月23日         Root.Lu
 */

package com.coocaa.framework.system;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.LogUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JoyStickManager {
    private static BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String action = intent.getAction();
            UsbDevice device = null;
            boolean bAttached = false;
            if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                bAttached = true;
            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
                device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            }
            if (device != null) {
                String str = action + "--name:" + device.getDeviceName() + " vendorID:"
                        + device.getVendorId() + " productID:" + device.getProductId()
                        + " deviceID:" + device.getDeviceId();
                LogUtils.d("JoyStickManager",
                        "action device key:" + device.getVendorId() + "/" + device.getProductId());
                for (String key : deviceMap.keySet()) {
                    LogUtils.d("JoyStickManager", "deviceMap key:" + key);
                }

                JoyStickDevice dev = deviceMap.get(device.getVendorId() + "/"
                        + device.getProductId());
                if (dev == null)
                    return;

                synchronized (callbacks) {
                    JoyStickDevice _device = dev;
                    if (bAttached) {
                        synchronized (devices) {
                            devices.add(_device);
                        }
                    } else {
                        List<JoyStickDevice> removedDevices = new ArrayList<JoyStickDevice>();
                        synchronized (devices) {
                            for (JoyStickDevice d : devices) {
                                if (d.name.equals(_device.name))
                                    removedDevices.add(d);
                            }
                            for (JoyStickDevice d : removedDevices)
                                devices.remove(d);
                        }
                    }
                    for (OnJoyStickChanged cb : callbacks) {
                        if (bAttached) {
                            cb.onJoyStickAttached(_device);
                        } else {
                            cb.onJoyStickDeattached(_device);
                        }
                    }
                }
            }
        }
    };

    public static class JoyStickDevice {
        public String name;
        public int vendorID, productID, deviceID;

        public JoyStickDevice() {
        }

        public JoyStickDevice(String name, int vendorID, int productID, int deviceID) {
            this.name = name;
            this.vendorID = vendorID;
            this.productID = productID;
            this.deviceID = deviceID;
        }
    }

    public static interface OnJoyStickChanged {
        void onJoyStickAttached(JoyStickDevice device);

        void onJoyStickDeattached(JoyStickDevice device);
    }

    private static Map<String, JoyStickDevice> deviceMap = new HashMap<String, JoyStickDevice>();
    private static List<JoyStickDevice> devices = new ArrayList<JoyStickDevice>();
    private static List<OnJoyStickChanged> callbacks = new ArrayList<OnJoyStickChanged>();

    static {
        deviceMap.put(Integer.parseInt(0x11c0 + "", 10) + "/" + Integer.parseInt(0x5505 + "", 10),
                new JoyStickDevice("HJC Game [ BETOP CONTROLLER ]", 0x11c0, 0x5505, 0x0111));
        deviceMap.put(Integer.parseInt(0x11ff + "", 10) + "/" + Integer.parseInt(0x0007 + "", 10),
                new JoyStickDevice("AliTV GAMEPAD And-GA003", 0x11ff, 0x0007, 0x0110));
        deviceMap.put(Integer.parseInt(0x20bc + "", 10) + "/" + Integer.parseInt(0x5500 + "", 10),
                new JoyStickDevice("BETOP BFM GAMEPAD", 0x20bc, 0x5500, 0x0111));

        UsbManager usbManager = (UsbManager) CoocaaApplication.getContext().getSystemService(
                Context.USB_SERVICE);
        Map<String, UsbDevice> ds = usbManager.getDeviceList();
        for (String s : ds.keySet()) {
            UsbDevice device = ds.get(s);
            JoyStickDevice dev = deviceMap.get(device.getVendorId() + "/" + device.getProductId());
            if (dev == null)
                continue;
            synchronized (devices) {
                devices.add(dev);
            }
        }

        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        CoocaaApplication.getContext().registerReceiver(receiver, filter);
    }

    public static List<JoyStickDevice> getDeviceList() {
        List<JoyStickDevice> ret = new ArrayList<JoyStickDevice>();
        synchronized (devices) {
            ret.addAll(devices);
        }
        return ret;
    }

    public static void registerCallback(OnJoyStickChanged c) {
        synchronized (callbacks) {
            if (!callbacks.contains(c))
                callbacks.add(c);
        }
    }

    public static void removeCallback(OnJoyStickChanged c) {
        synchronized (callbacks) {
            callbacks.remove(c);
        }
    }
}
